#!/data/Software/mydan/perl/bin/perl
use strict;
use warnings;
use MYDan::Util::OptConf;
use FindBin qw( $RealBin );
use YAML::XS;

=head1 SYNOPSIS

 $0 apply
 $0 check

=cut

my $option = MYDan::Util::OptConf->load();
$option->assert() unless @ARGV;

die "nonode" unless $ENV{NODE};
die "noticket" unless $ENV{TICKETFILE};

sub success
{
    map{ print "$_:ok\n"; } split /,/, $ENV{NODE};
    exit;
}

my $config_str;
my $tasktemppath = "/tmp/buildin.kubestar.$ENV{TASKUUID}.config";

if( $ENV{CONFIGPATH} && -f $ENV{CONFIGPATH} )
{
    $config_str = `cat '$ENV{CONFIGPATH}'`;
    die "cp config fail: $!" if system "cp '$ENV{CONFIGPATH}' '$tasktemppath'";
}
else
{
    $config_str = `cat '$tasktemppath'`;
}

die "config null\n" if $config_str =~ /^[ \n]*$/;

for( 1 .. @ARGV -1 )
{
    $config_str =~ s/\$\{VERSION$_\}/$ARGV[$_]/g;
}

if( $ARGV[1] )
{
    $config_str =~ s/DEPLOYVERSION/$ARGV[1]/g;
}

die "\${VERSION\\d+} no replace" if $config_str =~ /\$\{VERSION\d+\}/;
die "DEPLOYVERSION no replace" if $config_str =~ /DEPLOYVERSION/;

my $config = eval{ YAML::XS::Load $config_str };
die "load config fail: $@" if $@;
die "load yaml config fail" unless $config && ref $config eq 'HASH';

my $ticket = eval{ YAML::XS::LoadFile $ENV{TICKETFILE} };
die "load ticket fail: $@" if $@;
die "load yaml ticket fail" unless $ticket && ref $ticket eq 'HASH';

my %config = ( %$ticket, %$config );

my @containers = ( $config{containers} && ref $config{containers} eq 'ARRAY' ) ? @{$config{containers}} : ( +{ image => $config{image}, name => $config{name} } );
die "nofind containers on config\n" unless @containers;

for my $container ( @containers )
{
    die "name format error" unless $container->{name} && $container->{name} =~ /^[\w:_\-\.\/]+$/;
    die "image format error" unless $container->{image} && $container->{image} =~ /^[\w:_\-\.\/]+$/;
}

my @argv = qw( vendor region cluster-name resource-type kubestar-addr access-key secret-key org namespace resource-name );

if( $ARGV[0] && $ARGV[0] eq 'apply' )
{
    my $argv = '';
    map{
        die "key '$_' undef in config or ticket" unless $config{$_};
        die "key '$_' format error" unless $config{$_} =~ /^[\w:_\-\.\/]+$/;
        $argv .= " --$_ \"$config{$_}\" ";
    }@argv;
   
    for my $container ( @containers )
    {
        $argv .= " --image '$container->{name}=$container->{image}'";
    }

    my $cmd  = "kubestarctl.v2 $argv patch";
    die "apply fail. return code is not 0\n" if system "$cmd 1>&2";

    success();
}

if( $ARGV[0] eq 'check' )
{
    my $argv = '';
    map{
        die "key '$_' undef in config or ticket" unless $config{$_};
        die "key '$_' format error" unless $config{$_} =~ /^[\w:_\-\.\/]+$/;
        $argv .= " --$_ \"$config{$_}\" " if $_ ne 'resource-name' && $_ ne 'image' && $_ ne 'name';
    }@argv;
 
    my $cmd  = "kubestarctl.v2 $argv list apps";

    my $timeout = $ENV{TIMEOUT} && $ENV{TIMEOUT} =~ /^\d+$/ ? time + $ENV{TIMEOUT} : time  +  60; 

    my %check; map{ $check{"$config{'resource-name'}::$config{namespace}::$config{'resource-type'}::$_->{image}"} = 1 }@containers;

    warn "------\ncheck table:\n";
    map{ warn "$_\n" }keys %check;
    warn "------\n";

    for( 1 .. 360 )
    {

        warn "check ...\n";

        my @re = `$cmd`;
        shift @re;

        my %tempcheck = %check;
        map{

           my @info = split /\s+/, $_;
           my ( $name, $namespace, $type, undef, $image, undef, $status ) = @info;
           ( $name, $namespace, $type, undef, undef, $image, undef, $status ) = @info if @info == 8;

           my $check = "${name}::${namespace}::${type}::${image}";
           warn "$check => $status\n" if $tempcheck{$check};
           delete $tempcheck{$check} if $status eq 'Running';
        }@re;

        last unless %tempcheck;

        sleep 10;
        die "check timeout.\n" if time > $timeout;
    }

    success();
}
